<?php
class LangDetector {
	public $index = array();
	private $languages = array();

	public function __construct()
	{
/*		$english = strip_tags(file_get_contents("./src/english.txt"));
		$this->adddocument($english, 'english');
		$french = strip_tags(file_get_contents("./src/french.txt"));
		$this->adddocument($french, 'french');
		$italian = strip_tags(file_get_contents("./src/italian.txt"));
		$this->adddocument($italian, 'italian');
		$dutch = strip_tags(file_get_contents("./src/dutch.txt"));
		$this->adddocument($dutch, 'dutch');
		
		$j_index = json_encode($this -> index);
		$j_lang = json_encode($this -> languages);
		$index_file = fopen("./src/langDetIndex.txt","w");
		$languages_file = fopen("./src/langDetLanguages.txt","w");
		fwrite($index_file,$j_index);
		fwrite($languages_file,$j_lang);
		fclose($index_file);
		fclose($languages_file);
*/
		$this -> index = json_decode(file_get_contents("./src/langDetIndexTrigrams.txt"), true);
		$this -> languages = json_decode(file_get_contents("./src/langDetLanguages.txt"), true);
	}
		
	/* add a document with the language */
	public function addDocument($document, $language) {
		if(!isset($this->languages[$language])) {
			$this->languages[$language] = 0;
		}
		
		$words = $this->getWords($document);
		/* for each words of the text */
		foreach($words as $match) {
			/* We get all the trigrams of the texts */
			$trigrams = $this->getNgrams($match);
			/* We get all the different trigrams and get also their frequency in the document */
			foreach($trigrams as $trigram) {
				if(!isset($this->index[$trigram])) {
					$this->index[$trigram] = array();
				}
				if(!isset($this->index[$trigram][$language])) {
					$this->index[$trigram][$language] = 0;
				}
				$this->index[$trigram][$language]++;
			}
			$this->languages[$language] += count($trigrams);
		}
	}

	public function detect($document) {
		/* We get all the words of the documents in an array */
		$words = $this->getWords($document);
		$trigrams = array();
		foreach($words as $word) {
			/* We get all the trigrams of the text */
			foreach($this->getNgrams($word) as $trigram) {
				/* If the trigram does not already exist, we create it */
				if(!isset($trigrams[$trigram])) {
					$trigrams[$trigram] = 0;
				}
				/* If the trigram already exist, we update the frequency of it
				   and if it does not already exist the value will be : 0 + 1 = 1 */
				$trigrams[$trigram]++;
			}
		}
		/* We have the sum of the frequency of all the trigrams */
		$total = array_sum($trigrams);
	
		$scores = array();
		foreach($trigrams as $trigram => $count) {
			if(!isset($this->index[$trigram])) {
					continue;
			}
			foreach($this->index[$trigram] as $language => $lCount) {
				/* if the score of a language does not exist, we set it to 0 */
				if(!isset($scores[$language])) {
						$scores[$language] = 0;
				}
				/*	To compute the score for each trigram in the document : 
					$lCount : number of trigrams in the data set equal to the trigram we are studying
					$this->languages[$language] : sum of frequency of all trigrams
					$count : number of trigrams that are equals to the trigrams we are studying
					$total : total number of trigrams in the documents	*/
				$score = ($lCount / $this->languages[$language]) * ($count / $total);
				//echo "( $lCount / $this->languages[$language] ) * ($count / $total) = $score <br />";
				//We update the value of the score of the language
				$scores[$language] += $score;
			}
		}
		/*we sort the scores of each languages */
		arsort($scores);
		/* We return the languages that has the higher value */
		return key($scores);
	}
	
	/* Return in an array all the words separatly for all the training set*/
	private function getWords($document) {
			$document = strtolower($document);
			preg_match_all('/\w+/', $document, $matches);
			return $matches[0];
	}
	
	/* return in an array, arrays of all the trigrams of the words that have 3 or more letters */
	/* ex: tennis ==> ([0] => ten, [1] => enn, [2] => nni, [3] => nis) */
	private function getNgrams($match, $n = 3) {
		$ngrams = array();
		$len = strlen($match);
		for($i = 0; $i < $len; $i++) {
			if($i > ($n - 2)) {
				$ng = '';
				for($j = $n-1; $j >= 0; $j--) {
					$ng .= $match[$i-$j];
				}
				$ngrams[] = $ng;
			}
		}
		return $ngrams;
	}
}
?>